package com.hailiao.beidou.message.ui.page.contacts

import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.ColumnScope
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.navigationBarsPadding
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
import com.d10ng.compose.ui.AppColor
import com.d10ng.compose.ui.AppShape
import com.d10ng.compose.ui.AppText
import com.d10ng.compose.ui.PageTransitions
import com.d10ng.compose.ui.base.Button
import com.d10ng.compose.ui.base.ButtonSize
import com.d10ng.compose.ui.base.ButtonType
import com.d10ng.compose.ui.base.CellGroup
import com.d10ng.compose.ui.base.CellRow
import com.d10ng.compose.ui.form.Search
import com.d10ng.compose.ui.navigation.IndexBar
import com.d10ng.compose.ui.navigation.NavBar
import com.hailiao.beidou.message.R
import com.hailiao.beidou.message.data.db.entity.ContactEntity
import com.hailiao.beidou.message.ui.page.destinations.ContactDetailScreenDestination
import com.hailiao.beidou.message.ui.view.NavBarIcon
import com.hailiao.beidou.message.utils.back
import com.hailiao.beidou.message.utils.go
import com.ramcosta.composedestinations.annotation.Destination
import com.ramcosta.composedestinations.annotation.RootNavGraph
import kotlinx.coroutines.launch

/**
 * 联系人界面
 * @Author d10ng
 * @Date 2024/3/2 15:33
 */
@RootNavGraph
@Destination(style = PageTransitions::class)
@Composable
fun ContactsScreen(
    model: ContactsScreenViewModel = viewModel()
) {
    val search by model.searchFlow.collectAsState()
    val data by model.dataFlow.collectAsState(initial = listOf())

    ContactsScreenView(
        data = data,
        search = search,
        onUpdateSearch = model::onUpdateSearch,
        onClickAdd = { go(ContactDetailScreenDestination(null).route) },
        onClickContact = { go(ContactDetailScreenDestination(it.number).route) }
    )
}

@Composable
private fun ContactsScreenView(
    data: List<ContactEntity> = listOf(),
    search: String = "",
    onUpdateSearch: (String) -> Unit = {},
    onClickAdd: () -> Unit = {},
    onClickContact: (ContactEntity) -> Unit = {}
) {
    Column(
        modifier = Modifier
            .fillMaxSize()
            .background(AppColor.Neutral.bg)
            .navigationBarsPadding()
    ) {
        NavBar(
            title = "通讯录",
            titleAlignment = Alignment.CenterStart,
            onClickBack = { back() }
        ) {
            NavBarIcon(iconId = R.drawable.contact_add, onClick = onClickAdd)
        }
        if (data.isEmpty()) {
            EmptyContent(onClickAdd)
        } else {
            DataContent(data, search, onUpdateSearch, onClickContact)
        }
    }
}

@Composable
private fun ColumnScope.EmptyContent(
    onClickImport: () -> Unit = {}
) {
    Column(
        modifier = Modifier
            .fillMaxSize()
            .weight(1f)
            .padding(19.dp),
        verticalArrangement = Arrangement.Center,
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        Image(
            painter = painterResource(id = R.drawable.contact_empty),
            contentDescription = null,
            modifier = Modifier.size(124.dp),
            contentScale = ContentScale.Fit
        )
        Text(
            text = "当前暂无通讯录信息，请先添加联系人",
            style = AppText.Normal.Tips.default,
            textAlign = TextAlign.Center,
            modifier = Modifier.padding(top = 19.dp)
        )
        Button(
            text = "点击添加",
            type = ButtonType.PRIMARY,
            size = ButtonSize.BIG,
            shape = AppShape.RC.Cycle,
            modifier = Modifier
                .padding(vertical = 30.dp)
                .width(249.dp),
            onClick = onClickImport
        )
    }
}

@Composable
private fun ColumnScope.DataContent(
    data: List<ContactEntity> = listOf(),
    search: String = "",
    onUpdateInputSearch: (String) -> Unit = {},
    onClickContact: (ContactEntity) -> Unit = {}
) {
    CellGroup {
        Search(
            value = search,
            onValueChange = onUpdateInputSearch,
            placeholder = "搜索名称、号码"
        )
    }
    val listState = rememberLazyListState()
    val scope = rememberCoroutineScope()
    IndexBar(
        modifier = Modifier
            .fillMaxSize()
            .weight(1f),
        onSelect = { value ->
            val index = data.indexOfFirst { it.nameFirst() == value }
            if (index >= 0) {
                scope.launch { listState.scrollToItem(index) }
            }
        }
    ) {
        LazyColumn(
            modifier = Modifier.fillMaxSize(),
            state = listState
        ) {
            itemsIndexed(data, { _, i -> i.number }) { idx, item ->
                val showTag = remember(data, idx, item) {
                    idx == 0 || (idx - 1 in data.indices && data[idx - 1].nameFirst() != item.nameFirst())
                }
                if (showTag) {
                    Text(
                        text = item.nameFirst().toString(),
                        style = AppText.Normal.Tips.default,
                        modifier = Modifier
                            .padding(start = 19.dp)
                            .padding(vertical = 4.dp)
                    )
                }
                ContactCell(item) { onClickContact(item) }
            }
        }
    }
}

private fun ContactEntity.nameFirst() = pinyin.first()

@Composable
private fun ContactCell(
    value: ContactEntity,
    onClick: () -> Unit = {}
) {
    CellRow(
        modifier = Modifier
            .background(Color.White)
            .clickable { onClick() }
            .padding(start = 19.dp, end = 35.dp),
        divider = true,
        dividerPaddingValues = PaddingValues(0.dp)
    ) {
        Text(
            text = value.name,
            style = AppText.Normal.Title.medium,
            modifier = Modifier
                .weight(1f)
                .padding(vertical = 17.dp),
            maxLines = 1,
            overflow = TextOverflow.Ellipsis
        )
        Text(
            text = value.number,
            style = AppText.Normal.Tips.medium,
            maxLines = 1
        )
    }
}

@Preview
@Composable
private fun ContactsScreenPreview() {
    ContactsScreenView()
}